const signature = {}

let hexcase = 0 /* hex output format. 0 - lowercase; 1 - uppercase */

signature.objKeySort = function(arys) {
    // 先用Object内置类的keys方法获取要排序对象的属性名，再利用Array原型上的sort方法对获取的属性名进行排序，newkey是一个数组
    var newkey = Object.keys(arys).sort()
    var newObj = {} // 创建一个新的对象，用于存放排好序的键值对
    for (var i = 0; i < newkey.length; i++) {
        // 遍历newkey数组
        newObj[newkey[i]] = arys[newkey[i]]
        // 向新创建的对象中按照排好的顺序依次增加键值对
    }
    return newObj // 返回排好序的新对象
}

signature.urlEncode = function(param = {}, key = null, encode = null) {
    // if (param == null) {
    //     return ''
    // }
    var paramStr = ''
    var t = typeof (param)
    if (t == 'boolean') {
        param = ''
    }
    if ((t == 'string' && param !== '') || t == 'number' || t == 'boolean') {
        paramStr += '&' + key + '=' + ((encode != null || encode) ? encodeURIComponent(param) : param)
    } else {
        for (var i in param) {
            var k = key == null ? i : key + (param instanceof Array ? '[' + i + ']' : '[' + i + ']')
            paramStr += signature.urlEncode(param[i], k, encode)
        }
    }
    return paramStr
}

signature.hex_sha1 = function(s) {
    if (s.indexOf('&') === 0) {
        s = s.substr(1, s.length)
    }
    return binb2hex(core_sha1(AlignSHA1(s)))
}

var core_sha1 = function(blockArray) {
    var x = blockArray // append padding
    var w = Array(80)
    var a = 1732584193
    var b = -271733879
    var c = -1732584194
    var d = 271733878
    var e = -1009589776
    for (var i = 0; i < x.length; i += 16) { // 每次处理512位 16*32
        var olda = a
        var oldb = b
        var oldc = c
        var oldd = d
        var olde = e
        for (var j = 0; j < 80; j++) { // 对每个512位进行80步操作

            if (j < 16) {
                w[j] = x[i + j]
            } else {
                w[j] = rol(w[j - 3] ^ w[j - 8] ^ w[j - 14] ^ w[j - 16], 1)
            }
            var t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)), safe_add(safe_add(e, w[j]), sha1_kt(j)))
            e = d
            d = c
            c = rol(b, 30)
            b = a
            a = t
        }
        a = safe_add(a, olda)
        b = safe_add(b, oldb)
        c = safe_add(c, oldc)
        d = safe_add(d, oldd)
        e = safe_add(e, olde)
    }
    return new Array(a, b, c, d, e)
}

var sha1_ft = function(t, b, c, d) {
    if (t < 20) {
        return (b & c) | ((~b) & d)
    }
    if (t < 40) {
        return b ^ c ^ d
    }
    if (t < 60) {
        return (b & c) | (b & d) | (c & d)
    }
    return b ^ c ^ d // t<80
}

var sha1_kt = function(t) {
    return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 : (t < 60) ? -1894007588 : -899497514
}

var safe_add = function(x, y) {
    var lsw = (x & 0xFFFF) + (y & 0xFFFF)
    var msw = (x >> 16) + (y >> 16) + (lsw >> 16)
    return (msw << 16) | (lsw & 0xFFFF)
}

var rol = function(num, cnt) {
    return (num << cnt) | (num >>> (32 - cnt))
}

var AlignSHA1 = function(str) {
    var nblk = ((str.length + 8) >> 6) + 1, blks = new Array(nblk * 16)
    for (var i = 0; i < nblk * 16; i++) {
        blks[i] = 0
    }
    for (i = 0; i < str.length; i++) {
        blks[i >> 2] |= str.charCodeAt(i) << (24 - (i & 3) * 8)
    }
    blks[i >> 2] |= 0x80 << (24 - (i & 3) * 8)
    blks[nblk * 16 - 1] = str.length * 8
    return blks
}

var binb2hex = function(binarray) {
    var hex_tab = hexcase ? '0123456789ABCDEF' : '0123456789abcdef'
    var str = ''
    for (var i = 0; i < binarray.length * 4; i++) {
        str += hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8 + 4)) & 0xF) +
        hex_tab.charAt((binarray[i >> 2] >> ((3 - i % 4) * 8)) & 0xF)
    }
    return str
}

signature.install = Vue => {

    Vue.prototype.objKeySort = signature.objKeySort
    Vue.prototype.urlEncode = signature.urlEncode
    Vue.prototype.hex_sha1 = signature.hex_sha1

}

export default signature
